package com.derbysoft.defender.mp.api.requester;

import com.derbysoft.defender.mp.api.ApiRequestException;
import com.derbysoft.defender.util.JsonUtil;
import com.derbysoft.defender.mp.api.response.ApiResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * <a href="https://mp.weixin.qq.com/wiki">微信公众平台技术文档</a>
 * <p/>
 * Created by Afee Lee on 2017-03-20 22:34
 *
 * @author Afee Lee
 * @version 1.0
 * @see Object
 * @since 1.8
 */
public abstract class AbstractRequester implements Requester {

    protected <T> T getForEntity(String url, Class<T> responseType, Object... urlVariables)
            throws ApiRequestException {
        ResponseEntity<String> entity = new RestTemplate().getForEntity(url, String.class, urlVariables);
        return execute(responseType, entity);
    }

    protected <T> T postForEntity(String url, Object request, Class<T> responseType, Object... urlVariables)
            throws ApiRequestException {
        ResponseEntity<String> entity = new RestTemplate().postForEntity(url, request, String.class, urlVariables);
        return execute(responseType, entity);
    }

    private <T> T execute(Class<T> responseType, ResponseEntity<String> entity) {
        HttpStatus httpStatus = entity.getStatusCode();
        Map<String, String> httpHeaders = entity.getHeaders().toSingleValueMap();

        if (!HttpStatus.OK.equals(httpStatus)) {
            //http error
            throw new ApiRequestException(httpStatus.getReasonPhrase())
                    .statusCode(httpStatus.value())
                    .httpHeaders(httpHeaders);
        }

        if (!entity.hasBody()) {
            //success and no response data
            return null;
        }

        String body = entity.getBody();
        if (body.contains("errcode") && body.contains("errmsg")) {
            ApiResponse response = JsonUtil.fromJson(body, ApiResponse.class);

            if ("0".equals(response.getErrcode())) {
                //success and no response data,请求成功
                return null;
            } else {
                //WeChat tell us something wrong
                throw new ApiRequestException(httpStatus.getReasonPhrase())
                        .statusCode(httpStatus.value())
                        .httpHeaders(httpHeaders)
                        .apiResponse(response);
            }
        } else {
            if (String.class.equals(responseType)) {
                return (T) body;
            }

            //success and has response data
            return JsonUtil.fromJson(body, responseType);
        }
    }
}
